package cn.com.lyj6851.modules.mp.service;

import cn.com.lyj6851.api.BusinessException;
import cn.com.lyj6851.api.MyShopException;
import cn.com.lyj6851.enums.AppFromEnum;
import cn.com.lyj6851.enums.BillDetailEnum;
import cn.com.lyj6851.enums.OrderInfoEnum;
import cn.com.lyj6851.enums.PayMethodEnum;
import cn.com.lyj6851.enums.PayTypeEnum;
import cn.com.lyj6851.modules.mp.config.WxPayConfiguration;
import cn.com.lyj6851.modules.order.service.YdyStoreOrderService;
import cn.com.lyj6851.modules.order.vo.YdyStoreOrderQueryVo;
import cn.com.lyj6851.modules.user.domain.YdyUser;
import cn.com.lyj6851.modules.user.domain.YdyUserRecharge;
import cn.com.lyj6851.modules.user.service.YdyUserRechargeService;
import cn.com.lyj6851.modules.user.service.YdyUserService;
import cn.com.lyj6851.modules.user.service.dto.WechatUserDto;
import cn.com.lyj6851.utils.IpUtil;
import cn.com.lyj6851.utils.RedisUtils;
import cn.com.lyj6851.utils.ShopKeyUtils;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.binarywang.wxpay.bean.entpay.EntPayRequest;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * @ClassName 微信支付WeixinPayService
 **/
@Service
@Slf4j
@AllArgsConstructor
public class WeixinPayService {
    private final RedisUtils redisUtils;
    private final YdyUserService userService;
    private final YdyStoreOrderService storeOrderService;
    private final YdyUserRechargeService userRechargeService;

    /**
     * 统一支付入口
     * @param orderId 单号
     * @param from 来源
     * @param attach 备注 普通支付还是充值
     * @param body 内容
     * @return Object
     */
    public Object unifyPay(String orderId, String from, String attach, String body) {
        long uid = 0;
        int payPrice = 0;
        BigDecimal bigDecimal = new BigDecimal(100);
        //普通支付
        if(BillDetailEnum.TYPE_3.getValue().equals(attach)){
            YdyStoreOrderQueryVo orderInfo = storeOrderService.getOrderInfo(orderId,null);
            if(ObjectUtil.isNull(orderInfo)) {
                throw new MyShopException("订单不存在");
            }
            if(orderInfo.getPaid().equals(OrderInfoEnum.PAY_STATUS_1.getValue())) {
                throw new MyShopException("该订单已支付");
            }

            if(orderInfo.getPayPrice().compareTo(BigDecimal.ZERO) <= 0) {
                throw new MyShopException("该支付无需支付");
            }

            uid = orderInfo.getUid().intValue();
            //计算分
            payPrice = bigDecimal.multiply(orderInfo.getPayPrice()).intValue();
        }else{ //充值
            YdyUserRecharge userRecharge = userRechargeService.getOne(Wrappers.<YdyUserRecharge>lambdaQuery()
                    .eq(YdyUserRecharge::getOrderId,orderId));
            if(userRecharge == null) {
                throw new BusinessException("充值订单不存在");
            }

            if(userRecharge.getPaid().equals(OrderInfoEnum.PAY_STATUS_1.getValue())) {
                throw new MyShopException("该订单已支付");
            }
            uid = userRecharge.getUid();
            payPrice = bigDecimal.multiply(userRecharge.getPrice()).intValue();
        }


        YdyUser ydyUser = userService.getById(uid);
        if(ydyUser == null) {
            throw new MyShopException("用户错误");
        }

        WechatUserDto wechatUserDto = ydyUser.getWxProfile();

        WxPayService wxPayService = null;
        if(AppFromEnum.ROUNTINE.getValue().equals(from)){
            wxPayService = WxPayConfiguration.getPayService(PayMethodEnum.WXAPP);
        }else if(AppFromEnum.APP.getValue().equals(from)){
            wxPayService = WxPayConfiguration.getPayService(PayMethodEnum.APP);
        }else{
            wxPayService = WxPayConfiguration.getPayService(PayMethodEnum.WECHAT);
        }
        WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
        orderRequest.setOutTradeNo(orderId);
        orderRequest.setTotalFee(payPrice);
        orderRequest.setSpbillCreateIp(IpUtil.getLocalIP());
        orderRequest.setNotifyUrl(this.getApiUrl() + "/api/wechat/notify");
        orderRequest.setBody(body);
        orderRequest.setAttach(attach);

        if(AppFromEnum.WEIXIN_H5.getValue().equals(from)){
            orderRequest.setTradeType("MWEB");
        }else if(AppFromEnum.APP.getValue().equals(from)){
            orderRequest.setTradeType("APP");
        } else{
            orderRequest.setTradeType("JSAPI");
            if(AppFromEnum.ROUNTINE.getValue().equals(from)){
                orderRequest.setOpenid(wechatUserDto.getRoutineOpenid());
            }else {
                orderRequest.setOpenid(wechatUserDto.getOpenid());
            }
        }
        try {
            return wxPayService.createOrder(orderRequest);
        }catch (WxPayException e) {
            log.info("支付错误信息：{}",e.getMessage());
            throw new BusinessException(e.getMessage());
        }
    }




    /**
     * 退款
     * @param orderId orderId
     * @param totalFee totalFee 单位分
     */
    public void refundOrder(String orderId, Integer totalFee) {

        YdyStoreOrderQueryVo orderInfo = storeOrderService.getOrderInfo(orderId,null);
        if(PayTypeEnum.YUE.getValue().equals(orderInfo.getPayType())) {
            return;
        }

        WxPayService wxPayService = WxPayConfiguration.getPayService(PayMethodEnum.WECHAT);
        WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();
        //订单总金额
        wxPayRefundRequest.setTotalFee(totalFee);
        wxPayRefundRequest.setOutTradeNo(orderId);
        wxPayRefundRequest.setOutRefundNo(orderId);
        //退款金额
        wxPayRefundRequest.setRefundFee(totalFee);
        wxPayRefundRequest.setNotifyUrl(this.getApiUrl() + "/api/notify/refund");

        try {
            wxPayService.refund(wxPayRefundRequest);
        } catch (WxPayException e) {
            log.info("退款错误信息：{}",e.getMessage());
            throw new BusinessException(e.getMessage());
        }
    }



    /**
     * 企业打款
     * @param openid 微信openid
     * @param no 单号
     * @param userName 用户姓名
     * @param amount 金额
     * @throws WxPayException
     */
    public void entPay(String openid,String no,String userName,Integer amount) throws WxPayException {
        WxPayService wxPayService = WxPayConfiguration.getPayService(PayMethodEnum.WECHAT);
        EntPayRequest entPayRequest = new EntPayRequest();

        entPayRequest.setOpenid(openid);
        entPayRequest.setPartnerTradeNo(no);
        entPayRequest.setCheckName("FORCE_CHECK");
        entPayRequest.setReUserName(userName);
        entPayRequest.setAmount(amount);
        entPayRequest.setDescription("提现");
        entPayRequest.setSpbillCreateIp(IpUtil.getLocalIP());
        wxPayService.getEntPayService().entPay(entPayRequest);

    }


    /**
     * 返回H5 url
     * @return url
     */
    private String getApiUrl(){
        String apiUrl = redisUtils.getY(ShopKeyUtils.getApiUrl());
        if(StrUtil.isBlank(apiUrl)){
            throw new MyShopException("请配置移动端api地址");
        }
        return apiUrl;
    }


}
